package com.hy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hy.entitys.hy_front_userdb.Ums_member;
import com.hy.entitys.hy_front_userdb.Us_tp;
import com.hy.service.IUms_memberService;
import com.hy.service.IUs_tpService;
import com.hy.service.LoginOauthService;
import com.hy.utils.*;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthAlipayRequest;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWeiboRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.TimeUnit;

/**
 * 第三方登录 - 服务
 * @Author: 是奕靜吖
 */
@Service
public class LoginOauthServiceImpl implements LoginOauthService {

    //会员基本信息 - 业务层
    @Autowired
    private IUms_memberService iums;
    //会员签名验证 - 登录 - 业务层
    @Autowired
    private IUs_tpService ius;
    //引入通用类型的redis模板 直接注入即可
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 第三方登录回调地址
     */
    @Value("${download.callBackBaseUrl}")
    private String callBackBaseUrl;

    /**
     * 手机号绑定页面
     */
    @Value("${download.Mobile_Binding}")
    private String Mobile_Binding;

    /**
     * 根据具体的授权来源,获取请求工具类
     * @param source
     * @return
     */
    private AuthRequest getAuthRequest(String source){
        AuthRequest authRequest = null;
        switch (source){
            //QQ登录
            case "qq":
                authRequest = new AuthQqRequest(AuthConfig.builder()
                        //QQ-APP ID
                        .clientId("101554389")
                        //QQ-APP Key
                        .clientSecret("6df0b63f3d73b1054f6de15f8ed9e694")
                        //QQ登录回调
                        .redirectUri(callBackBaseUrl+"/qq")
                        .build());
                break;
            //支付宝登录
            case "alipay":
                // 支付宝在创建回调地址时，不允许使用localhost或者127.0.0.1，所以这儿的回调地址使用的局域网内的ip
                authRequest = new AuthAlipayRequest(AuthConfig.builder()
                        //支付宝-APP ID
                        .clientId("2021002111684439")
                        //支付宝-应用私钥
                        .clientSecret("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDSCYCClHzRTCyhb6lSsIHLv81tuqszbZTFiFqrUmqrKR4SqJoapu9B7f0wLQw26WrgBN+aXBqIpCFAT/vYpfmIHfEvLGZqb4U6DMKaFDdV57E44T/c7TRobCwF9Cdru1SQR1Sma2ykcxmFraP0e2ULGM1xE1Boen3p68lApX28zxP3oud837UcmaQ7JxNQab3XUbfFiuZFePI5PSdkkYidJKP3BULFxkrXfqEdeM9kH3FEMocprvWLd4fd3Q15RFTp5c4Ipe03Rk5SrQx08UrbPdvTIsDLg3zK+UIM+maYJWj/6QKwAvHa0TxOuGTinaW9uENVmwfU2ca6JC679kaBAgMBAAECggEBAKh8btZQ/v92N6cYx59JcBVduxD22TbcBKeghftAlcjPpwwYq+YNW4hrvNrUiCPUgqNJxYUxtSc/Yl0QzFoyakVCn6LT3yQqaZjze3fWF72VqpiSOISk05GglIACJ01IbMGANut46SHSIvsVG5yXD6sjLkoy0CG/gRoQxtRQ7NhzYAE94DtC2JNgqg02gvbt14pzDzDQr8MEiIev3AcYPMehr38WmV33t7vje55I8KY8ZMUTDVVzAS+lSHRJ6aZC36dTWD6IzJOxAKoV4c+p9a0w/Pw3t0P42r6hmokEJnAzyHk6yXVsX/uISRUfW2Lz78eh6z+IHI2VSp4ATnl7RDECgYEA+NeLN4DwCU5rTYA+lNM8uJBuPWgemcF/a0GiL2GaKag5JKDzQdbI4K7ApmfkGT2A994ecOUzErc1029g7Bkqybw6tUrz0xpytjPmTszoHoJicplCAImyR/MVl8AURGWG+ugQEgGMNGAM2eKSSQ7unONYXFGfie/AtzkUGS6RRHsCgYEA2BQzppcVV6s7Oe6yk/dblKJJUhq7FbSrHFzerQa0bOxRbiceNtOZNhijOAl9V9Ka6iFrUUObE7nBJjH5e04Ai0Pb1TOSYGgQA23iPo35roDpEvOx8qD8gyrER8mBpiPr7g8a+iWVKHQVuMgBVOfiwUX2jRQODc9Z9d/eI+EkRjMCgYEAkyPgzhEP3nDgQhNy7c16OigtB2JptcEU9vb4T8wGvFscbuw86tF2NmUexUbpOYOEnwxYM6lTad2rljpltTWsd1012b1YL5uT+Oj3ZeED4AZ48ApvXKIPKTwzqGeLlGX0Sqit1/fST6X781pl5Y1OyrYjqXMaQxXhfnXhzIIco8ECgYEAwZHna3exYOY+mnlhdPiFDDQN5wWXT6yYFUKFIQ/+lg1mLX3RrWAFwtZzcYHezcwXh2ME1rnvtM4VX/go/PM1vYy+5NHccY0Hu2q24T8iy9cj9Rxm72qUi5TGXWEBSiqn8o2Jp0n/w0urIevadYt+MZJRerTamjiE6KTyRcYtTs0CgYBRvo+DCEiyXYBnECwghNEVD0xTIg9am+bKU55mmcMFzfaZXUS4zhotgRiUdU1x792RPYkbiYFrU/5v1wHmzGJsSkIFiqzi5avUC6TtiAH3axxYhFf2GIaR2Nt7clhUEhYfNIoDmlSUFQFVk3fne8MEZSaOCa/z+1BH3lmIR3Cm3g==")
                        //支付宝-公钥
                        .alipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtFDCcZsB+HM4TZnKvCk94SFNGZjTte0GxIqqrTkyqNFovHweBM5Z8/2tAO+Oj3wdYFFluGsqp0Y58E8f1NDz0q9tudcopiTMnf7Sb0uFOc+eTR+L+KtGqvPc+FglfQazv7E15TtCf9nt3UuuHPHZC3+jOjfF7Pm70OniatgYps02XlwqGxFd7wxqQdLVs8wXK6Ij5nZxLScS0vj1FhUgqTrMsz+w3MXoVog7jN2uwboxati7NM9o4wo/9f66O9WX4AfbvCCckL2maYjuTsYO6qDq4NGLCC/IXHdY0NZYYvlv9fEDlgWwG1+rIPvS5BnXBtjbfW7hWZrpSaig2ajvwIDAQAB")
                        //支付宝登录回调
                        .redirectUri(callBackBaseUrl+"/alipay")
                        .build());
                break;
            //微博登录
            case "weibo":
                authRequest = new AuthWeiboRequest(AuthConfig.builder()
                        //微博的APP ID
                        .clientId("17292014")
                        //微博的APP Key
                        .clientSecret("2754bdb37079f881da4e8335e1f07843")
                        .redirectUri(callBackBaseUrl + "/weibo")
                        .build());
                break;
            //错误请求
            default:
                System.out.println("请求错误!");
                break;
        }
        if (null == authRequest) {
            throw new AuthException("未获取到有效的Auth配置");
        }
        return authRequest;
    }

    /**
     * 授权请求地址
     * @param source
     * @return
     */
    @Override
    public HY_Result renderAuth(String source) {
        System.out.println("进入render--->授权:" + source);
        //获取第三方登录配置
        AuthRequest authRequest = getAuthRequest(source);
        //生成授权地址    传递uuid ---> 状态码
        String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
        System.out.println("authorizeUrl--->:" + authorizeUrl);
        return new HY_Result(ResultCode.SUCCESS,null,authorizeUrl);
    }

    /**
     * 授权回调地址
     * @param source
     * @param callback
     * @return
     */
    @Override
    public HY_Result login(String source, AuthCallback callback) {
        System.out.println("进入callback--->:" + source
                + "--->callback params：" + JSONObject.toJSONString(callback));
        AuthRequest authRequest = getAuthRequest(source);
        AuthResponse<AuthUser> authResponse = authRequest.login(callback);
        System.out.println("AuthUser--->:"+JSONObject.toJSON(authResponse));
        if (authResponse == null || (authResponse != null && authResponse.getCode() != 2000)){
            return HY_Result.AUTHORIZATION_FAILURE();
        }
        //第三方令牌
        AuthToken token = authResponse.getData().getToken();
        //从第三方获取的用户数据
        AuthUser data = authResponse.getData();
        //签名验证登录
        Us_tp ut = new Us_tp();
        //存储登录类型id
        switch (source){
            //QQ登录
            case "qq":
                ut.setUsTpTid(2);
                //存储签名(密码待加密)
                ut.setUsTpSign(Md5Utils.getMd5Code(token.getOpenId()));
                break;
            //支付宝登录
            case "alipay":
                //存储类型
                ut.setUsTpTid(4);
                //存储签名(密码待加密)
                ut.setUsTpSign(Md5Utils.getMd5Code(token.getUid()));
                break;
            //微博登录
            case "weibo":
                //存储类型
                ut.setUsTpTid(3);
                //存储签名(密码待加密)
                ut.setUsTpSign(Md5Utils.getMd5Code(token.getUid()));
                break;
            //错误请求
            default:
                throw new RuntimeException("登录类型有误!");
        }
        //登录状态
        HY_Result rs = ius.signLogin(ut);
        //赋予 第三方信息
        ThirdParty tp = new ThirdParty();
        //签名验证成功
        if (rs.isSuccess()){
            //根据uid查询 用户
            Ums_member um = iums.findUid(Integer.valueOf(rs.getData().toString()));
            if (!ObjectUtils.isEmpty(um)){
                //登录成功 JWT数据加密
                return ius.Um_JWT_Token(um);
            }
            //未查到用户
            return HY_Result.SERVER_ERROR();
        }
        //未注册-数据填充
        //登录类型
        tp.setSource(data.getSource());
        //用户名
        tp.setUsername(data.getUsername());
        switch (source){
            //QQ登录
            case "qq":
                //大头像地址
                tp.setFigureurl_qq(data.getRawUserInfo().getString("figureurl_qq"));
                //uuid
                tp.setUuid(data.getUuid());
                //性别
                if ("男".equals(data.getRawUserInfo().getString("gender"))){
                    tp.setGender("1");
                }
                tp.setGender("0");
                break;
            //支付宝登录
            case "alipay":
                //大头像地址
                tp.setAvatar(data.getAvatar());
                //uid
                tp.setUid(token.getUid());
                //性别
                if ("m".equals(data.getRawUserInfo().getString("gender"))){
                    tp.setGender("1");
                }
                tp.setGender("0");
                break;
            //微博登录
            case "weibo":
                //大头像地址
                tp.setAvatar_large(data.getRawUserInfo().getString("avatar_large"));
                //uid
                tp.setUid(token.getUid());
                //性别
                if ("m".equals(data.getRawUserInfo().getString("gender"))){
                    tp.setGender("1");
                }
                tp.setGender("0");
                break;
            //错误请求
            default:
                throw new RuntimeException("登录类型有误!");
        }
        //签名验证失败-未注册-返回第三方数据
        rs = HY_Result.USER_THERE();
        rs.setData(tp);
        //生成7位随机字符串
        String salt = SaltUtils.getSalt(7);
        //存储5分钟
        redisTemplate.opsForValue().set("ql"+salt,rs,5L, TimeUnit.MINUTES);
        //绑定手机号页面
        rs.setRedirectUrl(Mobile_Binding + salt);
        return rs;
    }

    /**
     * 取消授权登录
     * @param source 平台
     * @param token  token
     * @return
     */
    @Override
    public Object revokeAuth(String source, String token) {
        AuthRequest authRequest = getAuthRequest(source);
        try {
            authRequest.revoke(AuthToken.builder().accessToken(token).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return HY_Result.SUCCESS();
    }

    /**
     * 刷新Token
     * @param source
     * @param token
     * @return
     */
    @Override
    public Object refreshAuth(String source, String token) {
        AuthRequest authRequest = getAuthRequest(source);
        return authRequest.refresh(AuthToken.builder().refreshToken(token).build());
    }
}
